/*
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef _USB_COMMON_H
#define _USB_COMMON_H


#include <stdint.h>


// #include "pico/types.h"
// #include "structs/usb.h"



#define __PACKED    __attribute__((packed, aligned(1)))



// bmRequestType bit definitions
#define USB_REQ_TYPE_TYPE_MASK 		0x60u
#define USB_REQ_TYPE_TYPE_STANDARD 	0x00u
#define USB_REQ_TYPE_TYPE_CLASS 	0x20u
#define USB_REQ_TYPE_TYPE_VENDOR 	0x40u

#define USB_REQ_TYPE_RECIPIENT_MASK 		0x1fu
#define USB_REQ_TYPE_RECIPIENT_DEVICE 		0x00u
#define USB_REQ_TYPE_RECIPIENT_INTERFACE 	0x01u
#define USB_REQ_TYPE_RECIPIENT_ENDPOINT 	0x02u

#define USB_DIR_OUT 	0x00u
#define USB_DIR_IN 		0x80u

#define USB_TRANSFER_TYPE_CONTROL 		0x0
#define USB_TRANSFER_TYPE_ISOCHRONOUS 	0x1
#define USB_TRANSFER_TYPE_BULK 			0x2
#define USB_TRANSFER_TYPE_INTERRUPT 	0x3
#define USB_TRANSFER_TYPE_BITS 			0x3

// Descriptor types
#define USB_DT_DEVICE               0x01
#define USB_DT_CONFIG               0x02
#define USB_DT_STRING               0x03
#define USB_DT_INTERFACE            0x04
#define USB_DT_ENDPOINT             0x05
#define USB_DT_DEVICE_QUALIFIER     0x06
#define USB_DT_BOS                  0x0F

#define USB_REQUEST_GET_STATUS          0x0
#define USB_REQUEST_CLEAR_FEATURE       0x1
#define USB_REQUEST_SET_FEATURE         0x3
#define USB_REQUEST_SET_ADDRESS         0x5
#define USB_REQUEST_GET_DESCRIPTOR      0x6
#define USB_REQUEST_SET_DESCRIPTOR      0x7
#define USB_REQUEST_GET_CONFIGURATION   0x8
#define USB_REQUEST_SET_CONFIGURATION   0x9
#define USB_REQUEST_GET_INTERFACE       0xa
#define USB_REQUEST_SET_INTERFACE       0xb
#define USB_REQUEST_SYNC_FRAME          0xc

#define USB_REQUEST_MSC_GET_MAX_LUN     0xfe
#define USB_REQUEST_MSC_RESET           0xff

#define USB_FEAT_ENDPOINT_HALT          0x00
#define USB_FEAT_DEVICE_REMOTE_WAKEUP   0x01
#define USB_FEAT_TEST_MODE              0x02


typedef struct __PACKED {
    uint8_t bmRequestType;
    uint8_t bRequest;
    uint16_t wValue;
    uint16_t wIndex;
    uint16_t wLength;

} usb_setup_packet_t;


typedef struct __PACKED {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint16_t bcdUSB;
    uint8_t bDeviceClass;
    uint8_t bDeviceSubClass;
    uint8_t bDeviceProtocol;
    uint8_t bMaxPacketSize0;
    uint16_t idVendor;
    uint16_t idProduct;
    uint16_t bcdDevice;
    uint8_t iManufacturer;
    uint8_t iProduct;
    uint8_t iSerialNumber;
    uint8_t bNumConfigurations;

} usb_device_descriptor_t;


typedef struct __PACKED {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint16_t wTotalLength;
    uint8_t bNumInterfaces;
    uint8_t bConfigurationValue;
    uint8_t iConfiguration;
    uint8_t bmAttributes;
    uint8_t bMaxPower;

} usb_configuration_descriptor_t;


typedef struct __PACKED  {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint8_t bInterfaceNumber;
    uint8_t bAlternateSetting;
    uint8_t bNumEndpoints;
    uint8_t bInterfaceClass;
    uint8_t bInterfaceSubClass;
    uint8_t bInterfaceProtocol;
    uint8_t iInterface;

} usb_interface_descriptor_t;


typedef struct __PACKED {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint8_t bEndpointAddress;
    uint8_t bmAttributes;
    uint16_t wMaxPacketSize;
    uint8_t bInterval;

} usb_endpoint_descriptor_t;


typedef struct __PACKED {
    uint8_t bLength;
    uint8_t bDescriptorType;
    uint16_t  wArray[1];
} usb_string_descriptor_t;


typedef struct __PACKED {

    uint8_t bInterfaceNumber;           /* 对应 interface descriptor 中的 bInterfaceNumber 字段 */
    uint8_t rsvd1;
    uint8_t compatibleID[8];            /* windows 能支持的 compatible id, 后面未用字节补0. */
    uint8_t subCompatibleID[8];         /* sub compatible id, 未使用部分需要补0. */
    uint8_t rsvd2[6];

} usb_msos_function_section_t;


typedef struct __PACKED {
    uint32_t dwLength;          /* 包括后面 section 部分的总的字节长度. */
    uint16_t bcdVersion;        /* 固定值 0x0100, 表示版本号 1.00 */
    uint16_t wIndex;            /* descriptor index. 对应 setup packet 中的 wIndex 字段, 固定为 0x04. */
    uint8_t bCount;             /* the number of function sections */
    uint8_t rsvd[7];           /* reserved */

    /* 根据上面 bCount 的值, 决定数组成员个数. */
    // usb_msos_function_section_t  sections[x];

} usb_msos_compatid_descriptor_t;


typedef struct __PACKED {

    uint32_t dwPropertyDataLength;    /* 后面 PropertyData 字段的字节长度. */
    uint16_t wpropertyData[4];

} usb_msos_custom_property_data_t;


typedef struct __PACKED {
    
    uint32_t dwSize;                    /* 整个 section 的字节长度. */
    uint32_t dwPropertyDataType;        /* 1 : NULL-terminated Unicode String (REG_SZ) */
    uint16_t dwPropertyNameLength;      /* 后面 PropertyName 字段的字节长度, 一定是2的整数倍. */
    uint16_t wPropertyName[4];          /* Unicode */

    // usb_msos_custom_property_data_t

} usb_msos_custom_property_section_t;


typedef struct __PACKED {
    uint32_t dwLength;          /* 包括后面 section 部分的总的字节长度. */
    uint16_t bcdVersion;        /* 固定值 0x0100, 表示版本号 1.00 */
    uint16_t wIndex;            /* descriptor index. 对应 setup packet 中的 wIndex 字段, 固定为 0x04. */
    uint16_t wCount;            /* the number of property sections */

    /* custom propery section */
    // usb_msos_custom_property_section_t sections[x];

} usb_msos_ext_properties_descriptor_t;


#endif

